#!/usr/bin/env python
# _*_ coding: UTF-8 _*_
#Echo server with Forking


import socket, traceback, os, sys

def reap():
    while True:
        try:
            result = os.waitpid(-1, os.WNOHANG)
            if not result[0]: break

        except:
            break
        print "Reaped child process %d " % result[0]


host = ''
port = 51423

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host, port))
s.listen(1)

print "Parent at %d listening for connections" % os.getpid()

while True:
    try:
        clientsock, clietaddr = s.accept()
    except KeyboardInterrupt:
        raise
    except:
        traceback.print_exc()
        continue

    reap()

    try:
        pid = os.fork()
    except:
        print "BAD THING HAPPEND: for failed"
        clientsock.close()
        continue

    if pid:
        #父进程，关闭子进程的socket, 并返回到循环顶部
        print "New child", os.getpid()
        clientsock.close()
        continue
    else:
        # 子进程操作，关闭父进程的socket
        s.close()

    # 处理连接，父进程已经continue,所以此处都是子进程的操作
    try:
        print "Child from %s being handled by PID %d " % (clientsock.getpeername(), os.getpid())
        while True:
            data = clientsock.recv(4096)
            if not len(data):
                break

            clientsock.sendall(data)

    except (KeyboardInterrupt, SystemExit):
        raise
    except:
        traceback.print_exc()


    try:
        clientsock.close()
    except KeyboardInterrupt:
        raise
    except:
        traceback.print_exc()


    # 处理完成，子进程一定要结束，并且不能返回到循环
    sys.exit(0)
